package part6.interpreter;

import token.*;

public class Lexer {
    private final String text;
    private int pos;
    private Character currentChar;

    public Lexer(String text){
        this.text = text;
        this.pos = 0;
        this.currentChar = this.text.charAt(pos);
    }

    private void error() throws Exception {
        throw new Exception("Invalid character");
    }

    private void advance(){
        pos++;
        if (pos>text.length()-1){
            this.currentChar = null;
        }
        else {
            this.currentChar = text.charAt(pos);
        }
    }

    private void skipWhitespace(){
        while (this.currentChar!=null && isSpace(this.currentChar)){
            this.advance();
        }
    }

    private int integer(){
        StringBuilder sb = new StringBuilder();
        while (currentChar!=null && Character.isDigit(currentChar)){
            sb.append(currentChar);
            this.advance();
        }
        return Integer.parseInt(sb.toString());
    }

    private boolean isSpace(char c){
        return c == ' ' || c=='\t';
    }

    public Token getNextToken() throws Exception {
        while (currentChar != null){
            if (isSpace(this.currentChar)){
                this.skipWhitespace();
                continue;
            }
            if (Character.isDigit(currentChar)){
                return new TK_Integer(this.integer());
            }
            if (currentChar=='+'){
                this.advance();
                return new TK_Plus();
            }
            if (currentChar=='-'){
                this.advance();
                return new TK_Minus();
            }
            if (currentChar=='*'){
                this.advance();
                return new TK_Mul();
            }
            if (currentChar=='/'){
                this.advance();
                return new TK_Div();
            }
            if (currentChar=='('){
                this.advance();
                return new TK_Lparen();
            }
            if (currentChar==')'){
                this.advance();
                return new TK_Rparen();
            }
            this.error();
        }
        return new TK_EOF();
    }
}
